package com.yunxin.websitebox.dto;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.Data;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Data
public class SimpleQueryDTO {
    private List<Map<String,Boolean>> orders = new ArrayList<>();
    private Map<String,Integer> page = new HashMap<>();

    public <T> Page<T> page(){
        Page<T> pageObj = null;
        if(page.containsKey("page")&&(page.containsKey("size"))){
            pageObj = new Page<>(page.get("page"),page.get("size"));
        }else{
             pageObj = new Page<>(0,Integer.MAX_VALUE);
        }
        if(orders!=null){
            for(Map<String,Boolean> map : orders){
                for(String key: map.keySet()){
                    String column = humpToUnderline(key);
                    boolean asc = map.get(key);
                    OrderItem orderItem = new OrderItem();
                    orderItem.setColumn(column);
                    orderItem.setAsc(asc);
                    pageObj.getOrders().add(orderItem);
                }
            }
        }
        return pageObj;
    }

    public SimpleQueryDTO page(Integer page, Integer pageSize){
        this.page.put("page",page);
        this.page.put("size",pageSize);
        return this;
    }

    public SimpleQueryDTO order(String field,boolean asc){
        Map<String,Boolean> map = new HashMap<>();
        map.put(field,asc);
        orders.add(map);
        return this;
    }

    public <T> QueryWrapper<T> toQueryWrapperByEquals(){
        QueryWrapper<T> queryWrapper = new QueryWrapper<>();
        Class cls = getClass();
        Field[] fields = cls.getDeclaredFields();
        for(Field f: fields){
            try {
                f.setAccessible(true);
                Object oo = f.get(this);
                if(oo!=null){
                    queryWrapper.eq(humpToUnderline(f.getName()),f.get(this));
                }
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
        return queryWrapper;
    }

    public <T> QueryWrapper<T> toQueryWrapperByLikes(){
        QueryWrapper<T> queryWrapper = new QueryWrapper<>();
        Class cls = getClass();
        Field[] fields = cls.getDeclaredFields();
        for(Field f: fields){
            try {
                f.setAccessible(true);
                Object oo = f.get(this);
                if((oo!=null)){
                    if(oo instanceof String){
                        queryWrapper.like(humpToUnderline(f.getName()), f.get(this));
                    }else if((oo instanceof Integer)||(oo instanceof Long)||(oo instanceof Short)||oo instanceof Float||oo instanceof Double){
                        queryWrapper.eq(humpToUnderline(f.getName()),f.get(this));
                    }
                }
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
        return queryWrapper;
    }

    private String humpToUnderline(String humpName) {
        char[] charArray = humpName.toCharArray();
        StringBuffer buffer = new StringBuffer();
        int i = 0;

        for(int l = charArray.length; i < l; ++i) {
            if (charArray[i] >= 'A' && charArray[i] <= 'Z') {
                buffer.append("_").append(charArray[i] = (char)(charArray[i] + 32));
            } else {
                buffer.append(charArray[i]);
            }
        }

        return buffer.toString();
    }
}
